import os
import time
from fastapi import APIRouter,Depends,Form,UploadFile,File,BackgroundTasks
from sqlalchemy.orm import Session
from utils import token
from extend.get_db import get_db
from models.docs.docs_operation import \
    get_doc_pagenation, \
    get_doc_total, \
    doc_update, \
    delete_doc_by_id, \
    add_docs, \
    query_docs, \
    get_docs_query_totle, \
    get_doc_by_name, \
    save_upload, \
    share_db_add, \
    share_db_adds, \
    share_db_varify, \
    get_share_docs_pagenation, \
    get_doc_by_id, \
    get_pname_by_pid, \
    get_path_by_pid, \
    get_docs_by_ids, delete_share_by_id, get_share_id_by_doc_id,  delete_shareitem_by_shareid

from fastapi.responses import JSONResponse
from utils.get_random import get_random_num,get_timestemp
from utils.get_share import get_share_random_str
from utils.create_dir import create_dir,delete_path


from models.department.department_ret import DepartmentRet
import datetime
from fastapi.security import OAuth2PasswordRequestForm
from datetime import timedelta
from utils.get_zip_dir import zip_dir,zip_file_or_dir,zip_file

router = APIRouter(
    prefix="/docs"
)

@router.get("/doc_list",tags=["文档模块"])
def get_doc_list(pid:int,flag:int,page_size:int,current_page:int,id:str = Depends(token.parse_token),db:Session = Depends(get_db)):
    docs = get_doc_pagenation(db,page_size,current_page,pid,flag,id)
    doc_list=[]
    for doc in docs:
        this_doc={"id":doc[0],"name":doc[1],"flag":doc[2],"pid":doc[3],"filepath":doc[4],"filetype":doc[5],"create_time":doc[6]}
        doc_list.append(this_doc)
    total = get_doc_total(db,pid,flag,id)
    content = {
        "docs":doc_list,
        "pageSize":page_size,
        "pageTotal":total,
        "currentPage":current_page
    }
    return content


#用户修改，涉及到图片上次，所有得用FormData这种方式提交
@router.post("/edit",tags=["文档模块"])
def edit(
        id: int = Form(...),
        name: str = Form(...),
        user_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):
    doc_update(db,id,name)
    return {"code":200,"msg":"更新成功","id":id}


@router.post("/delete",tags=["文档模块"])
def delete_doc(department:DepartmentRet,user_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):
    id = department.id
    doc=get_doc_by_id(db,id)
    share_id=get_share_id_by_doc_id(db,doc.id)
    delete_shareitem_by_shareid(db, share_id)
    delete_share_by_id(db, share_id)
    delete_doc_by_id(db,id)
    delete_path(doc.filepath)  #删除指定路径的文件或文件夹
    print(f"Deleted file: {doc.filepath}")
    return JSONResponse(content={"code":200,"msg":"删除成功","id":id})


# 添加一级文件夹
@router.post("/add",tags=["文档模块"])
async def add(
        name: str = Form(...),
        pid:int = Form(...),

        user_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):
    docs = get_doc_by_name(db,name)
    if docs:
        return JSONResponse(content={"code":500,"msg":"该文件夹已存在，请重新输入"})

    base_dir = "uploads/docs/"+str(user_id)+"/"
    if pid == 0: # 一级文件夹
        path = base_dir + name
        create_dir(path)
    else:
        name_list = get_pname_by_pid(db,pid)
        new_name_list = list(reversed(name_list))
        new_name_list = "/".join(new_name_list)
        path = base_dir + new_name_list + "/" + name
        create_dir(path)

    add_docs(db, name, int(user_id), pid,path)

    return JSONResponse(content={"code":200,"msg":"添加成功"})


# 查询
@router.get("/query",tags=["文档模块"])
def query(
        q:str,
        page_size:int,
        current_page:int,
        pid:int,
        flag:int,
        user_id: str = Depends(token.parse_token),
        db: Session = Depends(get_db)):


    q = q.strip()
    docs = query_docs(db,q,page_size,current_page,pid,flag,user_id)
    total = get_docs_query_totle(db,q,pid,flag)
    doc_list=[]
    for doc in docs:
        this_doc={"id":doc[0],"name":doc[1],"flag":doc[2],"pid":doc[3],"filepath":doc[4],"filetype":doc[5],"create_time":doc[6]}
        doc_list.append(this_doc)
    content = {
        "docs":doc_list,
        "pageSize":page_size,
        "pageTotal":total,
        "currentPage":current_page
    }
    return content


# 文件上传
@router.post("/upload",tags=["文档模块"])
async def upload(
        file:UploadFile = File(...),
        pid:int = Form(...),
        flag:int = File(...),
        user_id: str = Depends(token.parse_token),
        db: Session = Depends(get_db)):

    rep = await file.read()

    # todo 文件名称可能会重复:12个随机数+时间戳
    new_prefix = get_random_num(12) + "-" + get_timestemp()
    new_name = new_prefix + "-" + file.filename
    # file_path = "uploads/docs/" + new_name
    file_path = get_path_by_pid(db,pid) + "/" + new_name

    with open(file_path,"wb") as f:
        f.write(rep)

    file_type = file.filename.rsplit(".", 1)[1]

    save_upload(db,new_name,pid,flag,file_path,file_type,int(user_id),file.filename)

    return {"code":200,"msg":"上传成功"}


# 分享
@router.post("/share_add",tags=["文档模块"])
def share_add(
        sharePwd:str = Form(None),
        numType:int = Form(...),
        doc_id: int = Form(...),
        shareNum:int = Form(...),
        share_type:int = Form(...),
        user_id: str = Depends(token.parse_token),
        db: Session = Depends(get_db)):

    # sharePwd == None 表示系统生成提取码

    # numType == 1 表示访问人数不限，shareNum值无所谓
    # numType == 2，shareNum 就是具体的值
    # 表示访问人数不限


    # 生成随机字符串
    share_url = get_share_random_str(16)
    # share_pwd进行判断，如果为空则自动生成，否则直接使用
    if sharePwd == None or sharePwd == "":
        sharePwd = get_share_random_str(4)

    # 根据有效期判断，传开始时间和结束时间
    end_time = datetime.datetime.now()
    if share_type != 1:
        if share_type == 2:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=30)
        if share_type == 3:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=7)
        if share_type == 4:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=1)


    state = 1
    share_db_add(
        db,int(user_id),
        share_url,sharePwd,
        share_type,end_time,
        state,numType,shareNum,
        doc_id
    )


    return {"code":200,"msg":"分享成功","share_url":share_url,"share_pwd":sharePwd}


# 多条分享
@router.post("/share_adds",tags=["文档模块"])
def share_adds(
        sharePwd:str = Form(None),
        numType:int = Form(...),
        doc_ids: str = Form(...),
        shareNum:int = Form(...),
        share_type:int = Form(...),
        user_id: str = Depends(token.parse_token),
        db: Session = Depends(get_db)):



    doc_ids = doc_ids.split(",")


    # 生成随机字符串
    share_url = get_share_random_str(16)
    # share_pwd进行判断，如果为空则自动生成，否则直接使用
    if sharePwd == None or sharePwd == "":
        sharePwd = get_share_random_str(4)

    # todo 根据有效期判断，传开始时间和结束时间
    end_time = datetime.datetime.now()
    if share_type != 1:
        if share_type == 2:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=30)
        if share_type == 3:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=7)
        if share_type == 4:
            now_time = datetime.datetime.now()
            end_time = now_time + datetime.timedelta(days=1)


    state = 1
    share_db_adds(
        db,int(user_id),
        share_url,sharePwd,
        share_type,end_time,
        state,numType,shareNum,
        doc_ids
    )


    return {"code":200,"msg":"分享成功","share_url":share_url,"share_pwd":sharePwd}

# share_token过期时间
EXPIRE_MINUTE = 60

@router.post("/share_varify",tags=["文档模块"])
def share_varify(user:OAuth2PasswordRequestForm = Depends(),db:Session = Depends(get_db)):
    share_url = user.username
    share_pwd = user.password

    share = share_db_varify(db,share_url,share_pwd)
    if share:
        # 生成token
        expire_time = timedelta(minutes=EXPIRE_MINUTE)
        ret_token = token.create_token({"sub": str(share.id)}, expire_time)
        content = {"code": 200, "msg": "校验成功", "share_token": ret_token}
        return JSONResponse(content=content)
    else:
        content = {"code": 500, "msg": "提取码错误"}
        return JSONResponse(content=content)

@router.get("/shares_doc_list",tags=["文档模块"])
def get_docs_by_share_id(
        page_size:int,
        current_page:int,
        share_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):

    docs = get_share_docs_pagenation(db,page_size,current_page,int(share_id))
    doc_list = []
    for doc in docs:
        this_doc = {"id": doc[0], "name": doc[1], "flag": doc[2], "pid": doc[3], "filepath": doc[4], "filetype": doc[5],"create_time":doc[6]}
        doc_list.append(this_doc)
    total = len(docs)

    if total != 0:

        content = {
            "code":200,
            "msg":"查询成功",
            "docs": doc_list,
            "pageSize": page_size,
            "pageTotal": total,
            "currentPage": current_page
        }
    else:
        content = {
            "code":500,
            "msg":"分享已过期",
            "pageTotal":0
        }

    return content



@router.get("/shares_child_doc_list",tags=["文档模块"])
def get_shares_child_doc_list(
        pid:int,flag:int,page_size:int,current_page:int,id:str = Depends(token.parse_token),db:Session = Depends(get_db)):
    docs = get_doc_pagenation(db,page_size,current_page,pid,flag)
    total = get_doc_total(db,pid,flag)
    doc_list=[]
    for doc in docs:
        this_doc={"id":doc[0],"name":doc[1],"flag":doc[2],"pid":doc[3],"filepath":doc[4],"filetype":doc[5]}
        doc_list.append(this_doc)
    content = {
        "docs":doc_list,
        "pageSize":page_size,
        "pageTotal":total,
        "currentPage":current_page
    }
    return content

# 单文件下载
@router.get("/shares_download",tags=["文档模块"])
def shares_download(
        doc_id:int,
        share_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):

    doc = get_doc_by_id(db,doc_id)
    if doc.flag == 2: # 文件，直接返回路径
        output_file = doc.filepath.rsplit("/", 1)[0] + "/" + doc.name + ".zip"
        zip_file(output_file,doc)
        return {"code":200,"msg":"查询成功","filepath":output_file}

    elif doc.flag == 1: # 文件夹，打包后返回打包后的路径
        output_file = doc.filepath.rsplit("/",1)[0] +"/" + doc.name + ".zip"
        # output_file = "../uploads/docs/一级文件夹.zip"
        # dir = "../uploads/docs/一级文件夹"
        dir = doc.filepath
        zip_dir(output_file, dir)
        return {"code": 200, "msg": "查询成功", "filepath": output_file}

    else: # 直接返回错误信息，该文件丢失了
        return {"code":500,"msg":"该文件丢失了"}


# def clear_zip(path:str,delay:int=10):
#     time.sleep(delay)  # 等待指定的时间间隔
#     os.remove(path)  # 删除文件


# 多文件下载
@router.post("/shares_downloads",tags=["文档模块"])
def shares_downloads(
        # background_tasks: BackgroundTasks,
        doc_ids:str = Form(...),
        share_id:str = Depends(token.parse_token),
        db:Session = Depends(get_db)):
    print(doc_ids)
    doc_ids = doc_ids.split(",")


    docs,pname,path = get_docs_by_ids(db,doc_ids)
    print("============docs")


    output_file = path.rsplit("/",1)[0] +"/" + pname + ".zip"
    zip_file_or_dir(db,output_file,docs)
    # background_tasks.add_task(clear_zip,output_file)
    print(output_file)
    return {"code": 200, "msg": "下载成功","filepath":output_file}


